package com.yhy.common.wechat.model;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.yhy.common.core.result.ResultCode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;

import java.io.Serializable;

@ApiModel(value = "微信统一响应对象")
@Data
@Accessors(chain = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class WxResult<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 是否成功：true，成功；false，失败
     */
    @ApiModelProperty(value = "状态", required = true, example = "true")
    private boolean success;

    /**
     * 成功时返回 ok，失败时返回具体错误消息
     */
    @ApiModelProperty(value = "内容", required = true, example = "ok")
    private String message;

    /**
     * 原始错误消息
     */
    @ApiModelProperty(value = "错误内容", required = true, example = "ok")
    private String errorMsg;

    /**
     * <P>业务代码</P>
     * 成功为0,失败时返回具体错误码
     */
    @ApiModelProperty(value = "业务代码", required = true, example = "0")
    private Integer code;

    /**
     * 成功时具体返回值，失败时为 null
     */
    @ApiModelProperty(value = "响应体", dataType = "Object")
    private T data;

    public static <T> WxResult<T> ok(T data) {
        return result(Boolean.TRUE, ResultCode.OK.getCode(), ResultCode.OK.getMsg(), ResultCode.OK.getMsg(), data);
    }

    @SuppressWarnings("unchecked")
    public static <T> WxResult<T> fail(WxErrorException e) {
        WxError err = e.getError();
        return result(Boolean.FALSE, err.getErrorCode(), err.getErrorMsg(), err.getErrorMsgEn(), (T) err.getJson());
    }

    @SuppressWarnings("unchecked")
    public static <T> WxResult<T> fail(WxPayException e) {
        return result(Boolean.FALSE, ResultCode.FAIL.getCode(), e.getReturnMsg(), e.getCustomErrorMsg(), (T) e.getXmlString());
    }

    private static <T> WxResult<T> result(boolean success, Integer code, String message, String errorMsg, T data) {
        WxResult<T> result = new WxResult<>();
        result.setSuccess(success);
        result.setCode(code);
        result.setMessage(message);
        result.setErrorMsg(errorMsg);
        result.setData(data);
        return result;
    }

}
